package com.ibeeking.found.upms.s.rest.service.impl;

import com.ibeeking.found.common.base.BaseDO;
import com.ibeeking.found.common.config.feign.GlobalClient;
import com.ibeeking.found.common.config.feign.MsgFeignClient;
import com.ibeeking.found.common.config.prop.FileOssProp;
import com.ibeeking.found.common.config.secret.RsaConfig;
import com.ibeeking.found.common.constants.DefaultPathConstant;
import com.ibeeking.found.common.constants.HeaderNounConstant;
import com.ibeeking.found.common.entity.*;
import com.ibeeking.found.common.enums.LoginRoleEnum;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.enums.SexEnum;
import com.ibeeking.found.common.enums.member.MemberSexEnum;
import com.ibeeking.found.common.response.ResponseCodeEnum;
import com.ibeeking.found.common.utils.UrlUtils;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.upms.api.common.dto.ChoiceShopDTO;
import com.ibeeking.found.upms.api.common.query.AccountLoginQuery;
import com.ibeeking.found.upms.api.feign.SystemShopClient;
import com.ibeeking.found.upms.s.rest.config.prop.UserConfigProp;
import com.ibeeking.found.upms.s.rest.service.*;
import com.ibeeking.found.upms.service.common.bo.*;
import com.ibeeking.found.upms.service.common.dos.ShopUserRelationDO;
import com.ibeeking.found.upms.service.common.dos.ShopUserDO;
import com.ibeeking.found.upms.service.common.dos.TenantUserDO;
import com.ibeeking.found.upms.service.common.param.ModifyMobileParam;
import com.ibeeking.found.upms.service.common.param.ShopUserParam;
import com.ibeeking.found.upms.service.common.param.UserFindPwdParam;
import com.ibeeking.found.upms.service.common.param.UserModifyPwdParam;
import com.ibeeking.found.upms.service.common.po.ShopUserGlobalPO;
import com.ibeeking.found.upms.service.common.po.TenantUserPO;
import com.ibeeking.found.upms.service.common.query.ShopUserPageQuery;
import com.ibeeking.found.upms.service.common.vo.ChoiceShopVO;
import com.ibeeking.found.upms.service.common.vo.CurrentUserVO;
import com.ibeeking.found.upms.service.common.vo.ShopUserPageVO;
import com.ibeeking.found.upms.service.common.vo.ShopUserVO;
import com.ibeeking.found.upms.service.mapper.ShopUserMapper;
import com.ibeeking.found.upms.service.mapper.TenantUserMapper;
import com.ibeeking.nematos.constants.enums.LogClassifyEnum;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.exception.EncryptException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.encryption.EncryptUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ShopUserServiceImpl
 * @Description 全局用户
 * @Author ibeeking
 * @Date 2020-12-01 18:36
 **/
@Service
public class ShopUserServiceImpl implements IShopUserService {

    private static final String USER_KEY_LOCK = "USER_KEY_LOCK:";

    @Resource
    private IShopUserRelationService shopShopUserServiceImpl;
    @Resource
    private ShopUserMapper shopUserMapper;
    @Resource
    private FileOssProp fileOssProp;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private MsgFeignClient msgClient;
    @Resource
    private SystemShopClient systemShopClient;
    @Resource
    private UserConfigProp userConfigProp;
    @Resource
    private RsaConfig rsaConfig;
    @Resource
    private IShopUserRoleService userRoleServiceImpl;
    @Resource
    private IShopRoleService roleServiceImpl;
    @Resource
    private GlobalClient globalClient;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private IShopRoleAuthService roleAuthServiceImpl;
    @Resource
    private TenantUserMapper tenantUserMapper;

    @Override
    public Page<ShopUserPageVO> pageList(Long shopId, ShopUserPageQuery query) {
        //查询当前商户下所有在职员工
        List<ShopUserRelationDO> shopUserRelationDos = shopShopUserServiceImpl.selectByCondition(shopId, query);
        if (Collections3.isEmpty(shopUserRelationDos)) {
            return new Page<>();
        }
        List<Long> userIds = shopUserRelationDos.stream().map(ShopUserRelationDO::getId).collect(Collectors.toList());
        LambdaQueryWrapper<ShopUserDO> queryWrapper = new LambdaQueryWrapper<>(ShopUserDO.class);
        queryWrapper
                .in(BaseDO::getId, userIds)
                .eq(StringUtils.isNotBlank(query.getUserCode()), ShopUserDO::getUserCode, query.getUserCode())
                .eq(null != query.getSex(), ShopUserDO::getSex, query.getSex())
                .like(StringUtils.isNotBlank(query.getName()), ShopUserDO::getName, query.getName())
                .like(StringUtils.isNotBlank(query.getMobile()), ShopUserDO::getMobile, query.getMobile())
                .like(StringUtils.isNotBlank(query.getTel()), ShopUserDO::getTel, query.getTel())
                .like(StringUtils.isNotBlank(query.getEmail()), ShopUserDO::getEmail, query.getEmail())
        ;

        Page<ShopUserDO> page = shopUserMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), queryWrapper);
        Page<ShopUserPageVO> result = BeanUtil.convertPage(page, ShopUserPageVO.class);
        //查询角色
        List<ShopUserRoleBO> shopUserRoleBos = userRoleServiceImpl.queryRoleIdsByUserIds(shopId, userIds);
        Map<Long, StringBuffer> map = Collections3.emptyMap();
        if (!Collections3.isEmpty(shopUserRoleBos)) {
            List<ShopRoleBO> shopRoleBos = roleServiceImpl.queryByIds(shopUserRoleBos.stream().map(ShopUserRoleBO::getRoleId).collect(Collectors.toList()));
            if (!Collections3.isEmpty(shopRoleBos)) {
                map = new HashMap<>();
                Map<Long, String> roleNameMap = shopRoleBos.stream().collect(Collectors.toMap(ShopRoleBO::getId, ShopRoleBO::getName));
                for (ShopUserRoleBO shopUserRoleBO : shopUserRoleBos) {
                    if (roleNameMap.containsKey(shopUserRoleBO.getRoleId())) {
                        if (map.containsKey(shopUserRoleBO.getUserId())) {
                            map.get(shopUserRoleBO.getUserId()).append(roleNameMap.get(shopUserRoleBO.getRoleId())).append(",");
                        } else {
                            map.put(shopUserRoleBO.getUserId(), new StringBuffer(roleNameMap.get(shopUserRoleBO.getRoleId())).append(","));
                        }
                    }
                }
            }
        }

        List<Long> createBys = shopUserRelationDos.stream().map(ShopUserRelationDO::getCreateBy).distinct().collect(Collectors.toList());
        ResponseResult<List<OperatorDTO>> responseResult = globalClient.queryByUserIds(createBys);
        Map<Long, String> userMap = null;
        if (null != responseResult && !Collections3.isEmpty(responseResult.getData())) {
            userMap = responseResult.getData().parallelStream().collect(Collectors.toMap(OperatorDTO::getId, OperatorDTO::getName, (s, a) -> a));
        }
        Map<Long, ShopUserRelationDO> shopUserMap = shopUserRelationDos.stream().collect(Collectors.toMap(ShopUserRelationDO::getId, s -> s, (s, a) -> a));
        for (ShopUserPageVO shopUserPageVO : result.getRecords()) {
            ShopUserRelationDO shopUserRelationDO = shopUserMap.get(shopUserPageVO.getId());
            if (null != shopUserRelationDO) {
                shopUserPageVO.setJob(shopUserRelationDO.getJob());
                shopUserPageVO.setJobName(1 == shopUserRelationDO.getJob() ? "在职" : "离职");
                shopUserPageVO.setLock(shopUserRelationDO.getLock());
                shopUserPageVO.setLockName(1 == shopUserRelationDO.getLock() ? "未锁定" : "已锁定");
            }

            if (map.containsKey(shopUserPageVO.getId())) {
                shopUserPageVO.setRoleName(map.get(shopUserPageVO.getId()).toString());
            }

            if (StringUtils.isNotBlank(shopUserPageVO.getImage())) {
                shopUserPageVO.setImage(UrlUtils.addUrlDomainName(fileOssProp.getHost(), shopUserPageVO.getImage()));
            }
            shopUserPageVO.setSexName(MemberSexEnum.getDescByCode(shopUserPageVO.getSex()));
            if (!CollectionUtils.isEmpty(userMap) && userMap.containsKey(shopUserPageVO.getCreateBy())) {
                shopUserPageVO.setCreateByName(userMap.get(shopUserPageVO.getCreateBy()));
            }
        }
        return result;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean add(Long shopId, ShopUserParam param) {
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            throw new BusinessException(ResponseCodeEnum.TENANT_ID_NOT_EXIST.getMsg());
        }
        //查询是否存在租户员工账号
        List<TenantUserPO> list = tenantUserMapper.selectAllByMobile(responseResult.getData(), param.getMobile());
        if (!Collections3.isEmpty(list)) {
            throw new BusinessException("该手机号已是租户员工，请删除后再添加到该商户");
        }

        ShopUserDO shopUserDO = BeanUtil.convertBean(param, ShopUserDO.class);
        shopUserDO.setUserCode(param.getMobile());
        shopUserDO.setCreateBy(UserUtils.getUserId());

        shopUserDO.setModifyTime(LocalDateTime.now());
        shopUserDO.setPublishStatus(PublishStatusEnum.ENABLE.getValue());
        if (redisUtils.tryLock(USER_KEY_LOCK + param.getMobile())) {
            try {
                Long id = checkUnique(shopUserDO);
                if (null == id) {
                    //查询是否存在当前员工，存在查询个人信息
                    List<ShopUserDO> shopUserDos = shopUserMapper.selectByMobile(responseResult.getData(), param.getMobile());
                    if (Collections3.isEmpty(shopUserDos)) {
                        //未上传头像设置默认头像
                        if (StringUtils.isBlank(param.getImage())) {
                            shopUserDO.setImage(DefaultPathConstant.DEFAULT_USER_HEAD_IMAGE);
                        }
                        //设置默认密码
                        shopUserDO.setPassword(passwordEncoder.encode(userConfigProp.getInitialPwd()));
                    } else {
                        ShopUserDO query = shopUserDos.get(0);
                        //校验是否当前租户下存在此账号
                        shopUserDO.setId(query.getId());
                        shopUserDO.setImage(query.getImage());
                        shopUserDO.setPassword(query.getPassword());
                    }
                    shopUserDO.setCreateTime(LocalDateTime.now());
                    //新增当前租户下商户员工信息
                    shopUserMapper.insert(shopUserDO);
                } else {
                    shopUserDO.setId(id);
                    shopUserMapper.updateById(shopUserDO);
                }
            } finally {
                redisUtils.unlock(USER_KEY_LOCK + param.getMobile());
            }
            //新增当前商户员工和商户关系
            shopShopUserServiceImpl.add(shopId, shopUserDO.getId());
            return true;
        }
        return false;
    }

    @Override
    public Boolean modify(ShopUserParam param) {
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            throw new BusinessException(ResponseCodeEnum.TENANT_ID_NOT_EXIST.getMsg());
        }
        ShopUserDO shopUserDO = BeanUtil.convertBean(param, ShopUserDO.class);
        shopUserDO.setUserCode(null);
        shopUserDO.setMobile(null);
        shopUserDO.setModifyBy(UserUtils.getUserId());
        shopUserDO.setModifyTime(LocalDateTime.now());
        if (redisUtils.tryLock(USER_KEY_LOCK + param.getId())) {
            try {
                //获取当前账号所属的所有租户下的商户
                List<ShopUserGlobalPO> shopUserGlobalPos = shopUserMapper.selectAllById(responseResult.getData(), param.getId());
                if (Collections3.isEmpty(shopUserGlobalPos)) {
                    throw new BusinessException(ResponseCodeEnum.DATA_NOT_EXIST_ERROR.getMsg());
                }
                return getBean().updateAllById(shopUserGlobalPos.stream().map(ShopUserGlobalPO::getTenantId).distinct().collect(Collectors.toList()), shopUserDO);
            } finally {
                redisUtils.unlock(USER_KEY_LOCK + param.getId());
            }
        }
        return false;
    }

    @Override
    public Boolean updateAllById(List<Integer> tenantIds, ShopUserDO shopUserDO) {
        shopUserDO.setModifyTime(LocalDateTime.now());
        tenantIds.stream().forEach(tenantId -> shopUserMapper.updateAllById(shopUserDO, tenantId));
        return true;
    }

    @Override
    public ShopUserVO view(Long id) {
        ShopUserBO shopUserBO = getBean().queryById(id);
        return BeanUtil.convertBean(shopUserBO, ShopUserVO.class);
    }

    @Override
    public ShopUserBO queryById(Long id) {
        ShopUserDO shopUserDO = shopUserMapper.selectById(id);
        shopUserDO.setImage(UrlUtils.addUrlDomainName(fileOssProp.getHost(), shopUserDO.getImage()));
        return JsonUtils.fromJson(shopUserDO, ShopUserBO.class);
    }

    @Override
    public Boolean changeStatus(Long shopId, Long id, Integer status) {
        if (getBean().isAdministrator(shopId, id)) {
            throw new BusinessException("不能锁定管理员");
        }
        return shopShopUserServiceImpl.lockUser(shopId, id, status);
    }

    @Override
    public Boolean isAdministrator(Long shopId, Long userId) {
        Long administratorId = roleServiceImpl.selectAdministratorId();
        List<ShopUserRoleBO> shopUserRoleBos = userRoleServiceImpl.queryRoleIdsByUserId(shopId, userId);
        if (Collections3.isEmpty(shopUserRoleBos)) {
            return false;
        }
        return shopUserRoleBos.parallelStream().map(ShopUserRoleBO::getRoleId).collect(Collectors.toList()).contains(administratorId);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean del(Long shopId, Long userId) {
        if (getBean().isAdministrator(shopId, userId)) {
            throw new BusinessException("不能删除管理员");
        }
        List<ShopUserRelationBO> shopUserRelationBos = shopShopUserServiceImpl.queryShopByUserIds(Arrays.asList(userId));
        List<Long> shopIds = shopUserRelationBos.stream().map(ShopUserRelationBO::getShopId).collect(Collectors.toList());
        if (!shopIds.contains(shopId)) {
            throw new BusinessException("当前商户不存在该员工");
        }
        List<ShopUserRelationBO> dels = shopUserRelationBos.stream()
                .filter(s -> s.getShopId().equals(shopId))
                .filter(s -> s.getJob().equals(PublishStatusEnum.ENABLE))
                .collect(Collectors.toList());
        if (!Collections3.isEmpty(dels)) {
            throw new BusinessException("请先离职员工后再删除");
        }
        if (shopIds.size() == 1) {
            shopUserMapper.deleteById(userId);
        }
        return shopShopUserServiceImpl.delete(shopId, userId);
    }

    @Override
    public Boolean modifyPwd(Long userId, UserModifyPwdParam userModifyPwdParam) {
        ShopUserBO shopUserBO = getBean().queryById(userId);
        String oldPwd;
        String newPwd;
        try {
            oldPwd = EncryptUtils.RsaEncrypt.decrypt(userModifyPwdParam.getOldPassword(), rsaConfig.getKeyPair().getPrivate());
            newPwd = EncryptUtils.RsaEncrypt.decrypt(userModifyPwdParam.getNewPassword(), rsaConfig.getKeyPair().getPrivate());
        } catch (Exception e) {
            throw new EncryptException("密码非用户输入密码");
        }
        if (!passwordEncoder.matches(oldPwd, shopUserBO.getPassword())) {
            throw new BusinessException("旧密码错误");
        }
        return getBean().modifyPassword(userId, newPwd);
    }

    @Override
    public Boolean modifyPassword(Long userId, String newPassword) {
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            throw new BusinessException(ResponseCodeEnum.TENANT_ID_NOT_EXIST.getMsg());
        }
        //获取当前账号所属的所有租户下的商户
        List<ShopUserGlobalPO> shopUserGlobalPos = shopUserMapper.selectAllById(responseResult.getData(), userId);
        if (Collections3.isEmpty(shopUserGlobalPos)) {
            throw new BusinessException(ResponseCodeEnum.DATA_NOT_EXIST_ERROR.getMsg());
        }
        ShopUserDO shopUserDO = new ShopUserDO();
        shopUserDO.setId(userId);
        shopUserDO.setModifyTime(LocalDateTime.now());
        shopUserDO.setPassword(StringUtils.isEmpty(newPassword) ? passwordEncoder.encode(userConfigProp.getInitialPwd()) : passwordEncoder.encode(newPassword));
        return getBean().updateAllById(shopUserGlobalPos.parallelStream().map(ShopUserGlobalPO::getTenantId).distinct().collect(Collectors.toList()), shopUserDO);
    }

    @Override
    public Boolean resetPwd(Long id) {
        return getBean().modifyPassword(id, "");
    }

    @Override
    public Boolean findPwd(UserFindPwdParam userFindPwdParam) {
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            throw new BusinessException(ResponseCodeEnum.TENANT_ID_NOT_EXIST.getMsg());
        }
        List<ShopUserDO> shopUserDos = shopUserMapper.selectByMobile(responseResult.getData(), userFindPwdParam.getPhone());
        if (Collections3.isEmpty(shopUserDos)) {
            shopUserDos = Collections3.emptyList();
        }
        List<ShopUserDO> collect = shopUserDos.stream().filter(s -> PublishStatusEnum.ENABLE.getValue().equals(s.getPublishStatus())).collect(Collectors.toList());
        if (Collections3.isEmpty(collect)) {
            throw new BusinessException("用户不存在");
        }

        ResponseResult<Boolean> responseResult1 = msgClient.checkVerificationCode(userFindPwdParam.getKey(), userFindPwdParam.getPhone(), userFindPwdParam.getVerificationCode());
        if (null == responseResult1 || null == responseResult1.getData() || !responseResult1.getData()) {
            throw new BusinessException("验证码错误或已过期");
        }
        String newPwd;
        try {
            newPwd = EncryptUtils.RsaEncrypt.decrypt(userFindPwdParam.getNewPassword(), rsaConfig.getKeyPair().getPrivate());
        } catch (Exception e) {
            throw new EncryptException("密码非用户输入密码");
        }
        return getBean().modifyPassword(collect.get(0).getId(), newPwd);
    }

    @Override
    public List<ChoiceShopVO> shops(CurrentUser currentUser) {
        List<Long> shopIds = null;
        if (LoginRoleEnum.SHOP.name().equalsIgnoreCase(currentUser.getLoginRole())) {
            shopIds = queryShopIds(currentUser.getId());
        } else if (LoginRoleEnum.TENANT.name().equalsIgnoreCase(currentUser.getLoginRole())) {
            //查询授权关系
            List<ShopRoleTenantAuthRoleBO> shopRoleTenantAuthRoleBos = roleAuthServiceImpl.queryAuthShopIds(null, currentUser.getId());
            shopIds = shopRoleTenantAuthRoleBos.stream().map(ShopRoleTenantAuthRoleBO::getShopId).distinct().collect(Collectors.toList());
        }
        if (Collections3.isEmpty(shopIds)) {
            LogUtils.warn(LogClassifyEnum.TRACE_LOG, "当前用户未拥有店铺");
            return Collections3.emptyList();
        }
        ResponseResult<List<ChoiceShopDTO>> responseResult = systemShopClient.queryAllShopByIds(shopIds);
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            LogUtils.warn(LogClassifyEnum.TRACE_LOG, "店铺信息查询失败");
            return Collections3.emptyList();
        }
        List<ChoiceShopVO> result = JsonUtils.jsonToList(responseResult.getData(), ChoiceShopVO.class);
        result.stream().forEach(choiceShopVO -> choiceShopVO.setKey(choiceShopVO.getTenantId() + "-" + choiceShopVO.getId()));
        return result;
    }

    @Override
    public LoginUserDTO queryAccountLogin(AccountLoginQuery query) {
        LoginUserDTO defaultUser = new LoginUserDTO();
        defaultUser.setMobile(query.getMobile());
        defaultUser.setJob(false);
        defaultUser.setLock(true);
        //查询所有租户id
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            return defaultUser;
        }
        List<ShopUserGlobalPO> shopUserGlobalPos = shopUserMapper.queryAccountLogin(responseResult.getData(), query.getMobile());
        if (Collections3.isEmpty(shopUserGlobalPos)) {
            return defaultUser;
        }
        List<ShopUserGlobalPO> logout = shopUserGlobalPos.stream().filter(s -> null == s.getShopId()).collect(Collectors.toList());
        if (!Collections3.isEmpty(logout)) {
            shopUserMapper.deleteUser(logout);
        }

        Map<Long, List<ShopUserGlobalPO>> loginMap = shopUserGlobalPos.stream().filter(s -> !s.getShopId().equals(0L)).collect(Collectors.groupingBy(ShopUserGlobalPO::getShopId));
        if (CollectionUtils.isEmpty(loginMap)) {
            return defaultUser;
        }
        ShopUserGlobalPO shopUserGlobalPO = shopUserGlobalPos.parallelStream()
                .filter(s -> PublishStatusEnum.ENABLE.getValue().equals(s.getPublishStatus()))
                .filter(s -> PublishStatusEnum.ENABLE.getValue().equals(s.getJob()))
                .filter(s -> PublishStatusEnum.ENABLE.getValue().equals(s.getLock()))
                .findAny()
                .orElse(shopUserGlobalPos.get(0));
        Integer tenantId = shopUserGlobalPO.getTenantId();
        LoginUserDTO result = BeanUtil.convertBean(shopUserGlobalPO, LoginUserDTO.class);
        result.setJob(PublishStatusEnum.ENABLE.getValue().equals(shopUserGlobalPO.getJob()));
        result.setLock(!PublishStatusEnum.ENABLE.getValue().equals(shopUserGlobalPO.getLock()));
        result.setLoginRole(shopUserGlobalPO.getShopId().equals(0L) ? LoginRoleEnum.TENANT.name() : LoginRoleEnum.SHOP.name());
        result.setIds(new ArrayList<>(loginMap.keySet()));
        if(tenantId!=null) {
            TenantDTO tenantDTO = queryTenantById(tenantId);
            if(tenantDTO != null){
                result.setIndustry(tenantDTO.getIndustry());
            }
        }
        return result;
    }

    @Override
    public List<Long> queryShopIds(Long userId) {
        //查询所有租户id
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            return Collections3.emptyList();
        }
        return shopUserMapper.queryShopIds(responseResult.getData(), userId);
    }

    @Override
    public UserInfoDTO queryLoginUser(HttpServletRequest request, Long userId) {
        String loginRole = request.getHeader(HeaderNounConstant.LOGIN_ROLE);
        String tenantId = request.getHeader(HeaderNounConstant.TENANT_ID);
        String shopId = request.getHeader(HeaderNounConstant.SHOP_ID);
        if (StringUtils.isBlank(loginRole) || StringUtils.isBlank(tenantId) || StringUtils.isBlank(shopId)) {
            throw new BusinessException("未知身份用户");
        }
        if (loginRole.equals(LoginRoleEnum.SHOP.name())) {
            //商户员工登录
            ShopUserBO shopUserBO = getBean().queryById(userId);
            if (null == shopUserBO) {
                throw new BusinessException(ResponseCodeEnum.DATA_NOT_EXIST_ERROR.getMsg());
            }
            UserInfoDTO userInfoDTO = BeanUtil.convertBean(shopUserBO, UserInfoDTO.class);
            userInfoDTO.setTenantId(Integer.valueOf(tenantId));
            userInfoDTO.setShopId(Long.valueOf(shopId));
            userInfoDTO.setLoginRole(LoginRoleEnum.SHOP);
            userInfoDTO.setJob(true);
            userInfoDTO.setPublishStatus(false);
            if(StringUtils.isNotEmpty(tenantId)) {
                TenantDTO tenantDTO = queryTenantById(Integer.valueOf(tenantId));
                if(tenantDTO != null){
                    userInfoDTO.setIndustry(tenantDTO.getIndustry());
                }
            }
            //查询用户角色
            List<ShopUserRoleBO> shopUserRoleBos = userRoleServiceImpl.queryRoleIdsByUserId(userInfoDTO.getShopId(), userId);
            Optional.ofNullable(shopUserRoleBos).ifPresent(l -> userInfoDTO.setRoleIds(l.parallelStream().map(ShopUserRoleBO::getRoleId).collect(Collectors.toList())));
            return userInfoDTO;
        } else if (loginRole.equals(LoginRoleEnum.TENANT.name())) {
            //租户用户登录
            TenantUserDO tenantUserDO = tenantUserMapper.selectOne(new LambdaQueryWrapper<>(TenantUserDO.class)
                    .eq(TenantUserDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                    .eq(TenantUserDO::getJob, PublishStatusEnum.ENABLE.getValue())
                    .eq(BaseDO::getId, userId)
            );
            if (null == tenantUserDO) {
                throw new BusinessException(ResponseCodeEnum.DATA_NOT_EXIST_ERROR.getMsg());
            }
            UserInfoDTO userInfoDTO = BeanUtil.convertBean(tenantUserDO, UserInfoDTO.class);
            userInfoDTO.setTenantId(Integer.valueOf(tenantId));
            userInfoDTO.setShopId(Long.valueOf(shopId));
            userInfoDTO.setLoginRole(LoginRoleEnum.TENANT);
            userInfoDTO.setJob(true);
            userInfoDTO.setPublishStatus(false);
            if(StringUtils.isNotEmpty(tenantId)) {
                TenantDTO tenantDTO = queryTenantById(Integer.valueOf(tenantId));
                if(tenantDTO != null){
                    userInfoDTO.setIndustry(tenantDTO.getIndustry());
                }
            }
            //查询用户角色
            List<ShopRoleTenantAuthRoleBO> shopRoleTenantAuthRoleBos = roleAuthServiceImpl.queryAuthShopIds(Long.valueOf(shopId), userId);
            userInfoDTO.setRoleIds(shopRoleTenantAuthRoleBos.stream().map(ShopRoleTenantAuthRoleBO::getShopRoleId).distinct().collect(Collectors.toList()));
            return userInfoDTO;
        }
        throw new BusinessException("未知身份用户");
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean logOff(Long shopId, Long userId) {
        if (getBean().isAdministrator(shopId, userId)) {
            throw new BusinessException("请转让管理员后再进行注销");
        }
        List<ShopUserRelationBO> shopUserRelationBos = shopShopUserServiceImpl.queryShopByUserIds(Arrays.asList(userId));
        List<Long> shopIds = shopUserRelationBos.stream().map(ShopUserRelationBO::getShopId).collect(Collectors.toList());
        if (shopIds.size() == 1) {
            ShopUserDO shopUserDO = new ShopUserDO();
            shopUserDO.setId(userId);
            shopUserDO.setPublishStatus(PublishStatusEnum.DISABLE.getValue());
            shopUserDO.setModifyTime(LocalDateTime.now());
            shopUserMapper.updateById(shopUserDO);
        }
        return shopShopUserServiceImpl.quitById(shopId, userId);
    }

    @Override
    public Boolean modifyMobile(CurrentUser currentUser, ModifyMobileParam param) {
        ResponseResult<Boolean> responseResult = msgClient.checkVerificationCode(param.getKey(), param.getMobile(), param.getVerificationCode());
        if (null == responseResult || null == responseResult.getData() || !responseResult.getData()) {
            throw new BusinessException("验证码错误或已过期");
        }
        List<ChoiceShopVO> shops = getBean().shops(currentUser);
        ShopUserDO userDO = new ShopUserDO();
        userDO.setId(currentUser.getId());
        userDO.setMobile(param.getMobile());
        userDO.setModifyTime(LocalDateTime.now());
        return getBean().updateAllById(shops.stream().map(ChoiceShopVO::getTenantId).distinct().collect(Collectors.toList()), userDO);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean quit(Long shopId, Long userId) {
        if (getBean().isAdministrator(shopId, userId)) {
            throw new BusinessException("不能离职管理员");
        }
        List<ShopUserRelationBO> shopUserRelationBos = shopShopUserServiceImpl.queryShopByUserIds(Arrays.asList(userId));
        List<Long> shopIds = shopUserRelationBos.stream().map(ShopUserRelationBO::getShopId).collect(Collectors.toList());
        if (!shopIds.contains(shopId)) {
            throw new BusinessException("当前商户不存在该员工");
        }
        if (shopIds.size() == 1) {
            ShopUserDO shopUserDO = new ShopUserDO();
            shopUserDO.setId(userId);
            shopUserDO.setPublishStatus(PublishStatusEnum.DISABLE.getValue());
            shopUserDO.setModifyTime(LocalDateTime.now());
            shopUserMapper.updateById(shopUserDO);
        }
        return shopShopUserServiceImpl.quitById(shopId, userId);
    }

    @Override
    public CurrentUserVO currentInfo(Long userId) {
        ResponseResult<List<Integer>> responseResult = globalClient.queryTenantIds();
        if (null == responseResult || Collections3.isEmpty(responseResult.getData())) {
            throw new BusinessException(ResponseCodeEnum.TENANT_ID_NOT_EXIST.getMsg());
        }
        List<ShopUserGlobalPO> shopUserGlobalPos = shopUserMapper.selectAllById(responseResult.getData(), userId);
        if (Collections3.isEmpty(shopUserGlobalPos)) {
            throw new BusinessException("用户不存在");
        }
        CurrentUserVO currentUserVO = BeanUtil.convertBean(shopUserGlobalPos.get(0), CurrentUserVO.class);
        currentUserVO.setSexName(SexEnum.getDescByCode(currentUserVO.getSex()));
        currentUserVO.setImage(UrlUtils.addUrlDomainName(fileOssProp.getHost(), currentUserVO.getImage()));
        return currentUserVO;
    }

    private Long checkUnique(ShopUserDO shopUserDO) {
        //手机号校验
        ShopUserDO shopUserDO1 = shopUserMapper.selectOne(new LambdaQueryWrapper<>(ShopUserDO.class)
                .ne(null != shopUserDO.getId(), ShopUserDO::getId, shopUserDO.getId())
                .and(
                        Wrapper -> Wrapper
                                .eq(StringUtils.isNotBlank(shopUserDO.getMobile()), ShopUserDO::getMobile, shopUserDO.getMobile())
                )
        );
        return null == shopUserDO1 ? null : shopUserDO1.getId();
    }
    private TenantDTO queryTenantById(Integer tenantId) {
        ResponseResult<TenantDTO> responseResult = globalClient.queryTenantById(tenantId);
        if (null == responseResult || null == responseResult.getData()) {
            throw new BusinessException("租户不存在");
        }
        return responseResult.getData();
    }
    private IShopUserService getBean() {
        return SpringBeanUtil.getBean(IShopUserService.class);
    }
}
